package com.morder.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import com.morder.application.BuildConfig;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
/**
 * 异步线程加载图片工具类
 * 使用说明：
 * BitmapManager bmpManager;
 * bmpManager = new BitmapManager(BitmapFactory.decodeResource(context.getResources(), R.drawable.loading));
 * bmpManager.loadBitmap(imageURL, imageView);
 * @author liux (http://my.oschina.net/liux)
 * @version 1.0
 * @created 2012-6-25
 */
public class BitmapManager {

  private static HashMap<String, SoftReference<Bitmap>> cache;
  private static ExecutorService pool;
  private static Map<ImageView, String> imageViews;
  private Bitmap defaultBmp;

  static {
    cache = new HashMap<String, SoftReference<Bitmap>>();
    pool = Executors.newFixedThreadPool(5); // 固定线程池
    imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
  }

  public BitmapManager() {
  }

  public BitmapManager(Bitmap def) {
    this.defaultBmp = def;
  }

  /**
   * 设置默认图片
   * 
   * @param bmp
   */
  public void setDefaultBmp(Bitmap bmp) {
    defaultBmp = bmp;
  }

  /**
   * 加载图片
   * 
   * @param url
   * @param imageView
   */
  public void loadBitmap(String url, ImageView imageView) {
    loadBitmap(url, imageView, this.defaultBmp, 0, 0);
  }

  /**
   * 加载图片-可设置加载失败后显示的默认图片
   * 
   * @param url
   * @param imageView
   * @param defaultBmp
   */
  public void loadBitmap(String url, ImageView imageView, Bitmap defaultBmp) {
    loadBitmap(url, imageView, defaultBmp, 0, 0);
  }

  /**
   * 加载图片-可指定显示图片的高宽
   * 
   * @param url
   * @param imageView
   * @param width
   * @param height
   */
  public void loadBitmap(String url, ImageView imageView, Bitmap defaultBmp, int width, int height) {
    imageViews.put(imageView, url);
    Bitmap bitmap = getBitmapFromCache(url);

    if (bitmap != null) {
      // 显示缓存图片
      imageView.setImageBitmap(bitmap);
    } else {
      // 加载SD卡中的图片缓存
      String filename = FileUtils.getFileName(url);
      String filepath = imageView.getContext().getFilesDir() + File.separator + filename;
      File file = new File(filepath);
      if (file.exists()) {
        // 显示SD卡中的图片缓存
        Bitmap bmp = ImageUtils.getBitmap(imageView.getContext(), filename);
        imageView.setImageBitmap(bmp);
      } else {
        // 线程加载网络图片
        imageView.setImageBitmap(defaultBmp);
        queueJob(url, imageView, width, height);
      }
    }
  }

  /**
   * 从缓存中获取图片
   * 
   * @param url
   */
  public Bitmap getBitmapFromCache(String url) {
    Bitmap bitmap = null;
    if (cache.containsKey(url)) {
      bitmap = cache.get(url).get();
    }
    return bitmap;
  }

  /**
   * 从网络中加载图片
   * 
   * @param url
   * @param imageView
   * @param width
   * @param height
   */
  public void queueJob(final String url, final ImageView imageView, final int width, final int height) {
    /* Create handler in UI thread. */
    final Handler handler = new Handler() {
      public void handleMessage(Message msg) {
        String tag = imageViews.get(imageView);
        if (tag != null && tag.equals(url)) {
          if (msg.obj != null) {
            imageView.setImageBitmap((Bitmap) msg.obj);
            try {
              // 向SD卡中写入图片缓存
              //ImageUtils.saveImage(imageView.getContext(), FileUtils.getFileName(url), (Bitmap) msg.obj);
              String filePath = BuildConfig.DREADER_DATA_ICON_PATH;
              System.out.println("url: " + url);
              String picName = url.substring(url.lastIndexOf("/") + 1, url.length());
              filePath = filePath + "/" + picName;
              System.out.println("picName: " + picName);
              System.out.println("filePath: " + filePath);
              ImageUtils.saveImageToSD(imageView.getContext(), filePath, (Bitmap) msg.obj, 100);
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
        }
      }
    };

    pool.execute(new Runnable() {
      public void run() {
        Message message = Message.obtain();
        message.obj = downloadBitmap(url, width, height);
        handler.sendMessage(message);
      }
    });
  }

  /**
   * 下载图片-可指定显示图片的高宽
   * 
   * @param url
   * @param width
   * @param height
   */
  private Bitmap downloadBitmap(String url, int width, int height) {
    Bitmap bitmap = null;
    try {
      // http加载图片
      bitmap = getNetBitmap(url);
      if (width > 0 && height > 0) {
        // 指定显示图片的高宽
        bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);
      }
      // 放入缓存
      cache.put(url, new SoftReference<Bitmap>(bitmap));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return bitmap;
  }

  private final static int RETRY_TIME = 3;
  
  private static Bitmap getNetBitmap(String url) throws Exception {
     System.out.println("image_url==> "+url);
    Bitmap bitmap = null;
    int time = 0;
    do {
      try {
        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet();
        request.setURI(new URI(url));
        HttpParams httpParameters = new BasicHttpParams();
        // 设置 请求超时时间
        HttpConnectionParams.setConnectionTimeout(httpParameters, TIMEOUT_SOCKET);
        HttpConnectionParams.setSoTimeout(httpParameters, TIMEOUT_SOCKET);
        //request.setHeader("Host", HOST);
        //request.setHeader("Connection", "Keep-Alive");
        HttpResponse response = client.execute(request);
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("statusCode: " + statusCode);
        if (statusCode != HttpStatus.SC_OK) {
          // throw Exception.http(statusCode);
          throw new Exception();
        }
        InputStream input = response.getEntity().getContent();
        bitmap = BitmapFactory.decodeStream(input);
        input.close();
        break;
      } catch (HttpException e) {
        time++;
        if (time < RETRY_TIME) {
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e1) {
          }
          continue;
        }
        // 发生致命的异常，可能是协议不对或者返回的内容有问题
        e.printStackTrace();
        // throw AppException.http(e);
//        throw new Exception();
      } catch (IOException e) {
        time++;
        if (time < RETRY_TIME) {
          try {
            Thread.sleep(1000);
          } catch (InterruptedException e1) {
          }
          continue;
        }
        // 发生网络异常
        e.printStackTrace();
        // throw AppException.network(e);
      } finally {
        // 释放连接
//        httpGet.releaseConnection();
//        httpClient = null;
      }
    } while (time < RETRY_TIME);
    return bitmap;
  }

  private final static int TIMEOUT_SOCKET = 20000;
  public static final String UTF_8 = "UTF-8";
  public final static String HOST = "www.oschina.net";// 192.168.1.213
                                                      // www.oschina.net

  static final class ApnException extends IOException {
    private static final long serialVersionUID = 1L;

    public ApnException(IOException e) {
      super(e.getMessage());
    }
  }
  
  public static interface Listener {
    public void OnResponse(boolean success, HttpResponse response);
  }
  
}